package com.lty.controller;

import cn.hutool.core.util.IdUtil;
import com.lty.common.BaseResponse;
import com.lty.common.ErrorCode;
import com.lty.common.ResultUtils;
import com.lty.redis.RateLimiter;
import com.lty.redis.RedisUtil;
import com.lty.util.CreateVerifyCode;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 验证码生成
 */
@Slf4j
@RestController
@RequestMapping("/captcha")
public class CaptchaController {

    /**
     * 验证码是否开启
     */
    @Value("${app.verify}")
    public boolean verify;

    @Resource
    public RedisUtil redisUtil;

    public static String CAPTCHA_KEY = "captcha:";

    /**
     * 生成验证码并返回图片
     */
    @RateLimiter(rate = 5, rateInterval = 5000L, ipLimit = true)
    @ApiOperation("生成验证码")
    @GetMapping("/generate")
    public BaseResponse<String> generateCaptcha(HttpServletResponse response) {
        // 生成随机4位数字验证码
        String code = CreateVerifyCode.randomDigit(4);
        String id = IdUtil.simpleUUID();
        log.info("验证码生成成功,id：{},code: {}", id, code);
        // 将验证码值存储到 redis 中
        redisUtil.set(CAPTCHA_KEY + id, code, 60L);
        return ResultUtils.success(id);
    }

    @ApiOperation("返回验证码图片")
    @GetMapping("/generate/{id}")
    public void generateCaptcha(HttpServletResponse response, @PathVariable("id") String id) throws IOException {
        String sessionCaptcha = redisUtil.get(CAPTCHA_KEY + id);
        if (sessionCaptcha == null) {
            throw new RuntimeException("验证码已过期");
        }
        CreateVerifyCode captcha = new CreateVerifyCode(120, 40, 4, 20, sessionCaptcha);
        // 设置响应类型为图片
        response.setContentType("image/png");
        // 输出验证码图片
        captcha.write(response.getOutputStream());
    }

    /**
     * 验证验证码
     */
    @ApiOperation("验证验证码")
    @GetMapping("/verify")
    public BaseResponse<String> verifyCaptcha(HttpServletRequest request, String id, String code) {
        String key = CAPTCHA_KEY + id;
        // 获取 redis 中存储的验证码
        String sessionCaptcha = redisUtil.get(key);
        // 如果验证未开启，则直接返回成功
        if (!verify) {
            redisUtil.remove(key);
            return ResultUtils.success("验证成功");
        }
        if (sessionCaptcha != null && sessionCaptcha.equalsIgnoreCase(code)) {
            redisUtil.remove(key);
            return ResultUtils.success("验证成功");
        } else {
            log.error("验证码验证失败, id: {}, code: {}, sessionCaptcha: {}", id, code, sessionCaptcha);
            return ResultUtils.error(ErrorCode.OPERATION_ERROR, "验证失败");
        }
    }
}
